#pragma once


#include <assert.h>
namespace qian {
	//template<class T>
	/*class vector
	{
	public:

	private:
		T* _a;
		size_t _size;
		size_t _capacity;
	};*/

	template<class T>
	class vector
	{
	public:
		typedef const T* const_iterator;
		typedef T* iterator;

		//普通迭代器
		iterator begin()
		{
			return _start;
		}

		iterator end()
		{
			return _finish;
		}
		//提供给const对象使用的迭代器，指向的内容不可以被修改
		const_iterator begin() const
		{
			return _start;
		}

		const_iterator end() const
		{
			return _finish;
		}

		//类模板的成员函数,迭代器区间初始化
		//函数模板  -- 目的支持任意容器迭代器区间初始化
		template <class InputIterator>
		vector(InputIterator first, InputIterator last)
		{
			//reserve(last - first);
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}

		//n个val构造
		vector(size_t n, const T& val = T())//缺省值不能给0，因为T可能是string，所以给匿名对象T()
		{
			reserve(n);
			while(n--)
			{
				push_back(val);
			}
		}
		
		//n个val构造，第一个参数为int类型
		vector(int n, const T& val = T())//缺省值不能给0，因为T可能是string，所以给匿名对象
		{
			reserve(n);
			while(n--)
			{
				push_back(val);
			}
		}
		//initializer_list构造
		vector(initializer_list<T> il)
		{
			reserve(il.size());
			for (auto e : il)
			{
				push_back(e);
			}
		}

		//默认构造
		/*vector()
			:_start(nullptr)
			, _finish(nullptr)
			, _endOfStorage(nullptr)
		{}*/
		//上下等价
		vector() = default; //强制编译器生成默认的

		// v2 (v1)
		vector(const vector<T>& v)
		{
			reserve(v.capacity());
			for (auto e : v) push_back(e);
		}

		void swap(vector<T>& v)
		{
			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_end_of_storage, v._end_of_storage);
		}

		// v1 = v3
		vector<T>& operator = (vector<T> v)
		{
			swap(v);
			return *this;
		}

		~vector()
		{
			if (_start)
			{
				delete[] _start;
				_start = _finish = _end_of_storage = nullptr;
			}
		}

		void reserve(size_t n) //开辟空间
		{
			if (n > capacity())
			{
				size_t oldsize = size(); //保存旧空间
				T* tmp = new T[n];
				if (_start)
				{
					//memcpy(tmp, _start, sizeof(T) * size()); //memcpy 进行的是浅拷贝
					for (size_t i = 0; i < oldsize; i++) //深拷贝,转移数据
					{
						tmp[i] = _start[i];
					}
					delete[] _start; //释放旧空间
				}
				_start = tmp;   //新空间的起点
				_finish = _start + oldsize;
				_end_of_storage = _start + n;
			}
		}

		void resize(size_t n, const T& value = T())
		{
			// 1、如果n小于当前的size，则数据个数缩小到n
			if (n <= size())
			{
				_finish = _start + n;
				return;
			}
			// 2、空间不够则增容
			if (n > capacity()) reserve(n);
			//3、将size扩大到n
			iterator it = _finish;
			iterator _finish = _start + n;
			while (it != _finish)
			{
				*it = value;
				++it;
			}
		}
		size_t capacity() const
		{
			return _end_of_storage - _start;
		}

		size_t size() const
		{
			return _finish - _start;
		}

		T& operator[](size_t i)
		{
			assert(i < size());
			return _start[i];
		}

		const T& operator[](size_t i) const
		{
			assert(i < size());
			return _start[i];
		}

		void push_back(const T& x)
		{
			if (_finish == _end_of_storage)
			{
				size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
				reserve(newcapacity); //扩容
			}
			*_finish = x; //插入数据
			++_finish; //尾部指针后移

			 //insert(end(), x);
		}

		void pop_back(const T& x)
		{
			/*assert(size() > 0);
			--_finish;*/

			 erase(--end());
		}

		iterator insert(iterator pos, const T& x)
		{
			assert(pos >= _start);
			assert(pos <= _finish);

			if (_finish == _end_of_storage)
			{
				//防止迭代器因为后面的扩容失效，所以要提前记录pos位置
				size_t len = pos - _start;
				//size_t len = size();

				size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
				reserve(newcapacity);

				pos = _start + len; //判断扩容之后os位置，防止野指针出现使迭代器失效
			}

			iterator end = _finish - 1; //后移
			while (end >= pos)
			{
				*(end + 1) = *end;
				--end;
			}

			*pos = x;
			++_finish;
			return pos;
		}

		iterator erase(iterator pos)
		{
			assert(pos >= _start);
			assert(pos < _finish);

			iterator it = pos + 1;
			while (it != _finish) //从pos + 1开始往前移动
			{
				*(it - 1) = *it;
				++it;
			}

			--_finish;
			return pos;
		}

	private:
		iterator _start = nullptr; //相当于_a
		iterator _finish = nullptr; //_a+size
		iterator _end_of_storage = nullptr; //_a + capacity
	};

	void test_vector1()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);
		v1.push_back(4);
		v1.push_back(4);

		for (size_t i = 0; i < v1.size(); i++)
		{
			cout << v1[i] << " ";

		}
		cout << endl;

		//迭代器遍历
		//int* it = v1.begin();
		// 封装
		cout << "遍历为：";
		vector<int>::iterator it = v1.begin();
		while (it != v1.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;

		//cout << typeid(it).name() << endl;

		//for循环遍历，实质上就是通过迭代器来实现的
		cout << "范围for遍历为：";
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

	}

	void test_vector2()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);
		v1.push_back(5);
		/*for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;*/

		v1.insert(v1.begin(), 0);
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

		cout << "删除第一个位置：";
		v1.erase(v1.begin());
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

		//v1.insert(v1.begin() + 2, 20);
		//for (auto e : v1)
		//{
		//	cout << e << " ";
		//}
		//cout << endl;


		int x;
		cin >> x;
		// 没有x就不插入，有x的前面插入 
		vector<int>::iterator it = find(v1.begin(), v1.end(), x);
		if (it != v1.end())
		{
			// insert以后it这个实参会不会失效？
			//v1.insert(it, 1000); //有点问题
			it = v1.insert(it, 1000);

			// 建议失效后迭代器不要访问。除非赋值更新一下这个失效的迭代器
			cout << *it << endl;
		}

		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
	}


	void test_vector3()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);
		v1.push_back(5);

		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
		int x;
		cin >> x;

		vector<int>::iterator it = find(v1.begin(), v1.end(), x);
		if (it != v1.end())
		{
			it = v1.erase(it);
			if (it != v1.end())cout << *it << endl;
		}
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
	}

	void test_vector4() //删除
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);
		v1.push_back(5);

		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
		int x;
		cin >> x;

		vector<int>::iterator it = find(v1.begin(), v1.end(), x);
		if (it != v1.end())
		{
			//v1.erase(it); //挂掉
			it = v1.erase(it);
			if (it != v1.end()) //不加这句话删除最后一个元素会挂掉
				cout << *it << endl; //帮助我们访问循环内的错误
		}
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
	}

	void test_vector5()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);
		v1.push_back(5);

		vector<int> v2(v1);

		for (auto e : v2)
		{
			cout << e << " ";
		}
		cout << endl;

		vector<int> v3;
		v3.push_back(10);
		v3.push_back(20);
		v3.push_back(30);

		v1 = v3;
		for (auto e : v3)
		{
			cout << e << " ";
		}
		cout << endl;
	}

	void test_vector6()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);
		v1.push_back(5);
		vector<int> v2(v1.begin() + 1, v1.end());
		for (auto e : v2)
		{
			cout << e << " ";
		}
		cout << endl;

		string s("hello");
		vector<int> v3(s.begin(), s.end());
		for (auto e : v3)
		{
			cout << e << " ";
		}
		cout << endl;
	}

	void test_vector7()
	{
		// C++内置类型进行了升序，也有构造
		int i = 0;
		int j(1);
		int k = int();
		int x = int(2);

		vector<string> v1(10);
		vector<string> v2(10, "xxx");

		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
		for (auto e : v2)
		{
			cout << e << " ";
		}
		cout << endl;

		vector<int> v3(10,1); //若没有迭代器函数区间匹配，可以将就运行
		//vector <int> v3(10u, 1); //因为调用的是unsigned那个
		for (auto e : v3)
		{
			cout << e << " ";
		}
		cout << endl;

		vector<int> v4(10, 1);
		for (auto e : v4)
		{
			cout << e << " ";
		}
		cout << endl;
	}


	class A
	{
	public:
		//单参数隐式类型转换
		A(int a1 = 0)
			:_a1(a1)
			, _a2(0)
		{}

		A(int a1, int a2) //多参数隐式类型转换
			:_a1(a1)
			, _a2(a2)
		{}
	private:
		int _a1;
		int _a2;
	};

	void test_vector8() //initializer_list构造测试
	{
		//多参数隐式类型转换
		A aa1(1, 1);
		//A aa2 = (1, 1);
		A aa2 = { 1, 1 }; // 多参数隐式类型转换
		A aa9{ 2,2 }; //不要

		A aa3(1);
		A aa4 = 1;

		A aa5(1);
		A aa6 = { 1 }; //不要
		A aa7{ 1 }; //不要

		const A& aa8 = { 1,1 };

		// 这里不是隐式类型转换，跟上面不一样，这里参数个数不固定
		/*vector<int> v1 = { 1,2,3,4,5,6 };
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;*/

		auto il1 = { 1,2,3,4,5,6 };

		vector<A> v3 = {1, A(1),A(2,2),A{2,2},{1},{2,2} };

		//隐式类型转换
		vector<int> v1({ 1,2,3,4,5 });
		vector<int> v2 = { 6,7,8,9,10 };
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
		for (auto e : v2)
		{
			cout << e << " ";
		}
	}

	void test_vector9()
	{
		vector<string>v1;
		v1.push_back("111111111");
		v1.push_back("111111111");
		v1.push_back("111111111");
		v1.push_back("111111111");
		v1.push_back("111111111");
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
	}

}

